import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import {
  FormGroup,
  FormControl,
  Validators,
  FormBuilder,
} from '@angular/forms';

@Component({
  selector: 'app-column-drawer',
  templateUrl: './column-drawer.component.html',
  styleUrls: ['./column-drawer.component.css'],
})
export class ColumnDrawerComponent implements OnInit {
  visible = false;
  currentColumn = 'column0';
  currentType = 'type0';

  validateForm!: FormGroup;
  listOfControl: Array<{ id: number; datatype: string; column: string }> = [];

  shouldClear: boolean = true;

  @Input() columns: any;
  @Output() result = new EventEmitter();
  open(): void {
    this.shouldClear = true;
    this.validateForm.reset();
    this.visible = true;
  }

  close(): void {
    this.visible = false;
  }

  import(importColumn: string[]) {
    this.shouldClear = false;
    this.validateForm.reset();
    this.visible = true;
    this.validateForm.controls[this.listOfControl[0].column].patchValue(
      importColumn[0]
    );
    for (let i = 1; i < importColumn.length; i++) {
      this.addField2(importColumn[i]);
    }
  }
  addField2(value: string): void {
    const id =
      this.listOfControl.length > 0
        ? this.listOfControl[this.listOfControl.length - 1].id + 1
        : 0;

    const control = {
      id,
      datatype: `type${id}`,
      column: `column${id}`,
    };
    const index = this.listOfControl.push(control);
    // console.log(this.listOfControl[this.listOfControl.length - 1]);
    this.validateForm.addControl(
      this.listOfControl[index - 1].column,
      new FormControl(value, [Validators.required, this.columnConfirm])
    );
    this.validateForm.addControl(
      this.listOfControl[index - 1].datatype,
      new FormControl(null, [Validators.required, this.typeConfirm])
    );
  }
  addField(e?: MouseEvent): void {
    if(e){
      e.preventDefault();
    }
    const id =
      this.listOfControl.length > 0
        ? this.listOfControl[this.listOfControl.length - 1].id + 1
        : 0;

    const control = {
      id,
      datatype: `type${id}`,
      column: `column${id}`,
    };
    const index = this.listOfControl.push(control);
    // console.log(this.listOfControl[this.listOfControl.length - 1]);
    this.validateForm.addControl(
      this.listOfControl[index - 1].column,
      new FormControl(null, [Validators.required, this.columnConfirm])
    );
    this.validateForm.addControl(
      this.listOfControl[index - 1].datatype,
      new FormControl(null, [Validators.required, this.typeConfirm])
    );
  }

  removeField(
    i: { id: number; datatype: string; column: string },
    e: MouseEvent
  ): void {
    e.preventDefault();
    if (this.listOfControl.length > 1) {
      const index = this.listOfControl.indexOf(i);
      this.listOfControl.splice(index, 1);
      // console.log(this.listOfControl);
      this.validateForm.removeControl(i.datatype);
      this.validateForm.removeControl(i.column);
    }
  }
  typeConfirm = (control: FormControl): { [s: string]: boolean } => {
    if (
      !control.value ||
      !this.validateForm.controls[this.currentColumn].value
    ) {
      return { required: true };
    } else if (
      this.columns.find(
        (i: { field: any }) =>
          i.field == this.validateForm.controls[this.currentColumn].value
      ) ||
      this.listOfControl
        .filter((i) => i.column != this.currentColumn)
        .map((i) => this.validateForm.controls[i.column].value)
        .includes(this.validateForm.controls[this.currentColumn].value)
    ) {
      return { error: true };
    }
    return {};
  };
  columnConfirm = (control: FormControl): { [s: string]: boolean } => {
    if (!control.value || !this.validateForm.controls[this.currentType].value) {
      return { required: true };
    } else if (
      this.columns.find((i: { field: any }) => i.field == control.value) ||
      this.listOfControl
        .filter((i) => i.column != this.currentColumn)
        .map((i) => this.validateForm.controls[i.column].value)
        .includes(control.value)
    ) {
      return { error: true };
    }
    return {};
  };
  submitForm(): void {
    if (this.validateForm.valid) {
      let item: { field: string; type: string }[] = [];
      this.listOfControl.map((control) => {
        item.push({
          field: this.validateForm.controls[control.column].value,
          type: this.validateForm.controls[control.datatype].value,
        });
      });
      let res: any = {};
      res.column = item;
      res.shouldClear = this.shouldClear;
      this.result.emit(res);
      this.close();
    } else {
      Object.values(this.validateForm.controls).forEach((control) => {
        if (control.invalid) {
          control.markAsDirty();
          control.updateValueAndValidity({ onlySelf: true });
        }
      });
    }
  }
  constructor(private fb: FormBuilder) {}

  ngOnInit(): void {
    this.validateForm = this.fb.group({});
    this.addField();
  }

  columnChange(e: any, i: number) {
    this.currentColumn = `column${i}`;
    this.currentType = `type${i}`;
    Promise.resolve().then(() =>
      this.validateForm.controls[`column${i}`].updateValueAndValidity()
    );
    Promise.resolve().then(() =>
      this.validateForm.controls[`type${i}`].updateValueAndValidity()
    );
  }

  typeChange(e: any, i: number) {
    this.currentColumn = `column${i}`;
    this.currentType = `type${i}`;
    Promise.resolve().then(() =>
      this.validateForm.controls[`column${i}`].updateValueAndValidity()
    );
    Promise.resolve().then(() =>
      this.validateForm.controls[`type${i}`].updateValueAndValidity()
    );
  }
}
